package com.geniusk.system.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.geniusk.common.core.JSONResult;
import com.geniusk.common.utils.PageUtil;
import com.geniusk.system.model.bo.role.*;
import com.geniusk.system.model.pojo.Group;
import com.geniusk.system.model.pojo.Menu;
import com.geniusk.system.model.pojo.Role;
import com.geniusk.security.annotation.PreFuncAuth;
import com.geniusk.security.core.LoginUser;
import com.geniusk.security.utils.SecurityUtil;
import com.geniusk.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 角色管理接口
 */
@RestController
@RequestMapping("/system/role")
public class RoleController {
    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private RoleGroupService roleGroupService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private GroupService groupService;

    /**
     * 查询角色（所有角色）
     * @return 角色列表
     */
    @GetMapping("/selectAllRole")
    public JSONResult selectAllRole() {
        List<Role> list = roleService.selectAllRole();
        return JSONResult.ok(list);
    }

    /**
     * ID查询角色
     * @param selectRoleByIdBO 角色
     * @return 角色信息
     */
    @PostMapping("/selectRoleById")
    @PreFuncAuth("SYS:ROLE:SELECT")
    public JSONResult selectRoleById(@Valid @RequestBody SelectRoleByIdBO selectRoleByIdBO) {
        Role role = roleService.selectRoleById(selectRoleByIdBO.getRoleId());
        LoginUser loginUser = SecurityUtil.getLoginUser();
        List<Menu> menuList;
        if(loginUser.getIsRoot()){
            menuList = menuService.selectAllMenu(new Menu());
        }else{
            HashMap<String,Object> hashMap = new HashMap<>();
            hashMap.put("userId",loginUser.getUserId());
            menuList = menuService.selectMenuByUserId(hashMap);
        }
        Group group = new Group();
        List<Group> groupList = groupService.selectAllGroup(group);
        Map<String,Object> result = new HashMap<>();
        result.put("role",role);
        result.put("menuCheckedKeys",menuService.selectMenuByRoleId(selectRoleByIdBO.getRoleId()));
        result.put("menuList",menuList);
        result.put("groupCheckedKeys",roleGroupService.selectGroupByRoleId(selectRoleByIdBO.getRoleId()));
        result.put("groupList",groupList);
        return JSONResult.ok(result);
    }

    /**
     * 分页查询角色
     * @param selectRoleByPageBO 角色
     * @return 角色列表
     */
    @PostMapping("/selectRoleByPage")
    @PreFuncAuth("SYS:ROLE:SELECT")
    public JSONResult selectRoleByPage(@Valid @RequestBody SelectRoleByPageBO selectRoleByPageBO) {
        int pageNum = selectRoleByPageBO.getPageNum();
        int pageSize = selectRoleByPageBO.getPageSize();
        Role role = JSONUtil.parse(selectRoleByPageBO).toBean(Role.class);
        PageUtil.startPage(pageNum,pageSize);
        List<Role> roleList = roleService.selectRoleByPage(role);
        Map<String,Object> result = PageUtil.getResultTableData(roleList);
        return JSONResult.ok(result);
    }

    /**
     * 添加角色
     * @param insertRoleBO 角色
     * @return 添加结果
     */
    @PostMapping("/insertRole")
    @PreFuncAuth("SYS:ROLE:INSERT")
    public JSONResult insertRole(@Valid @RequestBody InsertRoleBO insertRoleBO) {
        //查询角色名称是否存在
        boolean isExist = roleService.selectRoleNameIsExist(insertRoleBO.getRoleName());
        if(isExist){
            return JSONResult.errorMsg("角色名称已经存在");
        }
        if(insertRoleBO.getMenuIds().length > 0){
            boolean menuIdIsExist = menuService.selectMenuIsExistByMenuIds(insertRoleBO.getMenuIds());
            if(!menuIdIsExist){
                return JSONResult.errorMsg("菜单不存在");
            }
        }
        if(insertRoleBO.getGroupIds().length > 0){
            boolean groupIdIsExist = groupService.selectGroupIsExistByGroupIds(insertRoleBO.getGroupIds());
            if(!groupIdIsExist){
                return JSONResult.errorMsg("组织不存在");
            }
        }
        Role role = JSONUtil.parse(insertRoleBO).toBean(Role.class);
        Long roleId = IdUtil.getSnowflake().nextId();
        role.setRoleId(roleId);
        role.setCreateBy(SecurityUtil.getUsername());
        int rows = roleService.insertRole(role);
        roleMenuService.insertRoleMenu(role);
        roleGroupService.insertRoleGroup(role);
        Map<String,Object> result = new HashMap<>();
        result.put("rows",rows);
        return JSONResult.ok(result);
    }

    /**
     * 修改角色
     * @param updateRoleBO 角色
     * @return 修改结果
     */
    @PostMapping("/updateRole")
    @PreFuncAuth("SYS:ROLE:UPDATE")
    public JSONResult updateRole(@Valid @RequestBody UpdateRoleBO updateRoleBO) {
        if(updateRoleBO.getGroupIds() != null && updateRoleBO.getGroupIds().length > 0){
            boolean groupIdIsExist = groupService.selectGroupIsExistByGroupIds(updateRoleBO.getGroupIds());
            if(!groupIdIsExist){
                return JSONResult.errorMsg("组织不存在");
            }
        }
        if(updateRoleBO.getMenuIds() != null && updateRoleBO.getMenuIds().length > 0){
            boolean menuIdIsExist = menuService.selectMenuIsExistByMenuIds(updateRoleBO.getMenuIds());
            if(!menuIdIsExist){
                return JSONResult.errorMsg("菜单不存在");
            }
        }
        Role role = JSONUtil.parse(updateRoleBO).toBean(Role.class);
        role.setUpdateBy(SecurityUtil.getUsername());
        int rows = roleService.updateRole(role);
        roleMenuService.insertRoleMenu(role);
        roleGroupService.insertRoleGroup(role);
        Map<String,Object> result = new HashMap<>();
        result.put("rows",rows);
        return JSONResult.ok(result);
    }

    /**
     * 删除角色
     * @param deleteRoleByIdsBO 角色ID
     * @return 删除结果
     */
    @PostMapping("/deleteRoleByIds")
    @PreFuncAuth("SYS:ROLE:DELETE")
    public JSONResult deleteRoleByIds(@Valid @RequestBody DeleteRoleByIdsBO deleteRoleByIdsBO) {
        int rows = roleService.deleteRoleByIds(deleteRoleByIdsBO.getRoleIds());
        Map<String,Object> result = new HashMap<>();
        result.put("rows",rows);
        return JSONResult.ok(result);
    }
}
